//
//
//  Created by danal on 13-4-8.
//  Copyright (c) 2013年 danal. All rights reserved.
//

#import "Device+CLExtension.h"

#import "sys/utsname.h"

#import <net/if.h>
#import <net/if_dl.h>
#import <sys/sysctl.h>

#import <mach/mach_time.h>

@implementation NSBundle (CLExtension)
/// 对比版本号，是否为新版本
+ (BOOL)isNewVersion:(NSString *)appVersion {
    if (appVersion == nil){
        return NO;
    }
    return [[self appBuild] compare:appVersion] == NSOrderedAscending;
}

/// app版本号
+ (NSString *)appVersion {
    return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
}

/// appBuild号
+ (NSString *)appBuild {
    return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
}

/// 通过资源名称返回资源的路径
+ (NSString *)pathForResource:(NSString *)res {
    return [[NSBundle mainBundle] pathForResource:res ofType:nil];
}

/// 通过资源名称返回资源的url路径
+ (NSURL *)urlForResource:(NSString *)res {
    return [[NSBundle mainBundle] URLForResource:res withExtension:nil];
}


///// 系统多语言
//+ (NSArray*)appleLanguages {
//    return [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];
//}

///// 当前系统语言是否是中文
//+ (BOOL)isZhHansLanguages {
//    return [[self appleLanguages].firstObject isEqualToString:@"zh-Hans"];
//}

@end

@implementation UIScreen (CLExtension)

+ (CGRect)screenBounds {
    return [[UIScreen mainScreen] bounds];
}

+ (CGSize)screenSize {
    return [UIScreen screenBounds].size;
}

+ (CGFloat)screenWidth {
    return [UIScreen screenSize].width;
}

+ (CGFloat)screenHeight {
    return [UIScreen screenSize].height;
}

@end

CGRect ScreenBounds() {
    return [UIScreen screenBounds];
}

CGSize screenSize() {
    return [UIScreen screenSize];
}

CGFloat ScreenWidth() {
    return [UIScreen screenWidth];
}

CGFloat ScreenHeight() {
    return [UIScreen screenHeight];
}


#import <AudioToolbox/AudioToolbox.h>
@implementation UIDevice (CLExtension)

+ (BOOL)isPhone {
    return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone;
}

+ (BOOL)isPad{
    return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
}

+ (BOOL)isJailbroken {
    BOOL jailbroken = NO;
    NSString *cydiaPath = @"/Applications/Cydia.app";
    NSString *aptPath = @"/private/var/lib/apt/";
    if ([[NSFileManager defaultManager] fileExistsAtPath:cydiaPath]) {
        jailbroken = YES;
    }
    if ([[NSFileManager defaultManager] fileExistsAtPath:aptPath]) {
        jailbroken = YES;
    }
    return jailbroken;
}

+ (void)playVibrate{
    SystemSoundID soundID = kSystemSoundID_Vibrate;
    AudioServicesPlaySystemSound(soundID);
}

+ (void)playEffect:(NSString *)soundFile {
    SystemSoundID soundID;
    NSString *path = [[NSBundle mainBundle] pathForResource:soundFile ofType:nil];  //caf,wav
    CFStringRef strRef = CFStringCreateWithCString(NULL, [path cStringUsingEncoding:NSUTF8StringEncoding], kCFStringEncodingUTF8);
    CFURLRef fileURL = CFURLCreateWithString(NULL, strRef, NULL);
    AudioServicesCreateSystemSoundID(fileURL,&soundID);
    AudioServicesPlaySystemSound(soundID);
    CFRelease(strRef);
    CFRelease(fileURL);
}

/// mac 地址
+ (NSString *)MACAddress {
    
    int mib[6];
    size_t len;
    char *buf;
    unsigned char *ptr;
    struct if_msghdr *ifm;
    struct sockaddr_dl *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    
    if ((mib[5] = if_nametoindex("en0")) == 0) {
        NSLog(@"if_nametoindex error");
        return nil;
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        NSLog(@"sysctl, take 1");
        return nil;
    }
    
    if ((buf = malloc(len)) == NULL) {
        NSLog(@"Could not allocate memory");
        return nil;
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        NSLog(@"sysctl, take 2");
        free(buf);
        return nil;
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    free(buf);
    
    return outstring;
}

+ (NSString *)platform {
    
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];

    return deviceString;
}

#pragma mark - 将设备Model Identifier转为Generation
+ (NSString *)deviceType {
    
    NSString *platform = [self platform];
    
    if ([platform isEqualToString:@"i386"])             return @"Simulator";
    if ([platform isEqualToString:@"x86_64"])        return @"Simulator";
    
    if([platform rangeOfString:@"iPhone"].location != NSNotFound){
        return iPhonePlatform(platform);
    }
    if([platform rangeOfString:@"iPad"].location != NSNotFound){
        return iPadPlatform(platform);
    }
    if([platform rangeOfString:@"iPod"].location != NSNotFound){
        return iPodPlatform(platform);
    }
    if([platform rangeOfString:@"AirPods"].location != NSNotFound){
        return AirPodsPlatform(platform);
    }
    if([platform rangeOfString:@"AppleTV"].location != NSNotFound){
        return AppleTVPlatform(platform);
    }
    if([platform rangeOfString:@"Watch"].location != NSNotFound){
        return AppleWatchPlatform(platform);
    }
    if([platform rangeOfString:@"HomePod"].location != NSNotFound){
        return HomePodPlatform(platform);
    }
    
    return @"Unknown iOS Device";
}

#pragma mark - iPhone
NSString *iPhonePlatform(NSString *platform){
    
    //2007年1月发布，更新一种机型：iPhone
    if ([platform isEqualToString:@"iPhone1,1"])    return @"iPhone";
    //2008年6月发布，更新一种机型：iPhone 3G
    if ([platform isEqualToString:@"iPhone1,2"])    return @"iPhone 3G";
    //2009年6月发布，更新一种机型：iPhone 3G
    if ([platform isEqualToString:@"iPhone2,1"])    return @"iPhone 3GS";
    //2010年6月发布，更新一种机型：iPhone 4
    if ([platform isEqualToString:@"iPhone3,1"])    return @"iPhone 4";
    if ([platform isEqualToString:@"iPhone3,2"])    return @"iPhone 4";
    if ([platform isEqualToString:@"iPhone3,3"])    return @"iPhone 4";
    //2011年10月发布，更新一种机型：iPhone 4s
    if ([platform isEqualToString:@"iPhone4,1"])    return @"iPhone 4s";
    //2012年9月发布，更新一种机型：iPhone 5
    if ([platform isEqualToString:@"iPhone5,1"])    return @"iPhone 5";
    if ([platform isEqualToString:@"iPhone5,2"])    return @"iPhone 5";
    //2013年9月发布，更新二种机型：iPhone 5c、iPhone 5s
    if ([platform isEqualToString:@"iPhone5,3"])    return @"iPhone 5c";
    if ([platform isEqualToString:@"iPhone5,4"])    return @"iPhone 5c";
    if ([platform isEqualToString:@"iPhone6,1"])    return @"iPhone 5s";
    if ([platform isEqualToString:@"iPhone6,2"])    return @"iPhone 5s";
    //2014年9月发布，更新二种机型：iPhone 6、iPhone 6 Plus
    if ([platform isEqualToString:@"iPhone7,2"])    return @"iPhone 6";
    if ([platform isEqualToString:@"iPhone7,1"])    return @"iPhone 6 Plus";
    //2015年9月发布，更新二种机型：iPhone 6s、iPhone 6s Plus
    if ([platform isEqualToString:@"iPhone8,1"])    return @"iPhone 6s";
    if ([platform isEqualToString:@"iPhone8,2"])    return @"iPhone 6s Plus";
    //2016年3月发布，更新一种机型：iPhone SE
    if ([platform isEqualToString:@"iPhone8,4"])    return @"iPhone SE";
    //2016年9月发布，更新二种机型：iPhone 7、iPhone 7 Plus
    if ([platform isEqualToString:@"iPhone9,1"])    return @"iPhone 7";
    if ([platform isEqualToString:@"iPhone9,3"])    return @"iPhone 7";
    if ([platform isEqualToString:@"iPhone9,2"])    return @"iPhone 7 Plus";
    if ([platform isEqualToString:@"iPhone9,4"])    return @"iPhone 7 Plus";
    //2017年9月发布，更新三种机型：iPhone 8、iPhone 8 Plus、iPhone X
    if ([platform isEqualToString:@"iPhone10,1"])  return @"iPhone 8";
    if ([platform isEqualToString:@"iPhone10,4"])  return @"iPhone 8";
    if ([platform isEqualToString:@"iPhone10,2"])  return @"iPhone 8 Plus";
    if ([platform isEqualToString:@"iPhone10,5"])  return @"iPhone 8 Plus";
    if ([platform isEqualToString:@"iPhone10,3"])  return @"iPhone X";
    if ([platform isEqualToString:@"iPhone10,6"])  return @"iPhone X";
    //2018年10月发布，更新三种机型：iPhone XR、iPhone XS、iPhone XS Max
    if ([platform isEqualToString:@"iPhone11,8"])  return  @"iPhone XR";
    if ([platform isEqualToString:@"iPhone11,2"])  return @"iPhone XS";
    if ([platform isEqualToString:@"iPhone11,4"])  return @"iPhone XS Max";
    if ([platform isEqualToString:@"iPhone11,6"])  return @"iPhone XS Max";
    //2019年9月发布，更新三种机型：iPhone 11、iPhone 11 Pro、iPhone 11 Pro Max
    if ([platform isEqualToString:@"iPhone12,1"])  return  @"iPhone 11";
    if ([platform isEqualToString:@"iPhone12,3"])  return  @"iPhone 11 Pro";
    if ([platform isEqualToString:@"iPhone12,5"])  return  @"iPhone 11 Pro Max";
    //2020年4月发布，更新一种机型：iPhone SE2
    if ([platform isEqualToString:@"iPhone12,8"])  return  @"iPhone SE (2nd generation)";
    
    return [NSString stringWithFormat:@"Unknown iPhone Identifier:%@", platform];
}

#pragma mark - iPad
NSString *iPadPlatform(NSString *platform){
    
    if ([platform isEqualToString:@"iPad1,1"])   return @"iPad";
    if ([platform isEqualToString:@"iPad2,1"])   return @"iPad 2";
    if ([platform isEqualToString:@"iPad2,2"])   return @"iPad 2";
    if ([platform isEqualToString:@"iPad2,3"])   return @"iPad 2";
    if ([platform isEqualToString:@"iPad2,4"])   return @"iPad 2";
    if ([platform isEqualToString:@"iPad3,1"])   return @"iPad (3rd generation)";
    if ([platform isEqualToString:@"iPad3,2"])   return @"iPad (3rd generation)";
    if ([platform isEqualToString:@"iPad3,3"])   return @"iPad (3rd generation)";
    if ([platform isEqualToString:@"iPad3,4"])   return @"iPad (4th generation)";
    if ([platform isEqualToString:@"iPad3,5"])   return @"iPad (4th generation)";
    if ([platform isEqualToString:@"iPad3,6"])   return @"iPad (4th generation)";
    if ([platform isEqualToString:@"iPad6,11"])  return @"iPad (5th generation)";
    if ([platform isEqualToString:@"iPad6,12"])  return @"iPad (5th generation)";
    if ([platform isEqualToString:@"iPad7,5"])   return @"iPad (6th generation)";
    if ([platform isEqualToString:@"iPad7,6"])   return @"iPad (6th generation)";
    if ([platform isEqualToString:@"iPad7,11"])   return @"iPad (7th generation)";
    if ([platform isEqualToString:@"iPad7,12"])   return @"iPad (7th generation)";
    if ([platform isEqualToString:@"iPad4,1"])   return @"iPad Air";
    if ([platform isEqualToString:@"iPad4,2"])   return @"iPad Air";
    if ([platform isEqualToString:@"iPad4,3"])   return @"iPad Air";
    if ([platform isEqualToString:@"iPad5,3"])   return @"iPad Air 2";
    if ([platform isEqualToString:@"iPad5,4"])   return @"iPad Air 2";
    if ([platform isEqualToString:@"iPad11,3"])   return @"iPad Air (3rd generation)";
    if ([platform isEqualToString:@"iPad11,4"])   return @"iPad Air (3rd generation)";
    if ([platform isEqualToString:@"iPad6,7"])   return @"iPad Pro (12.9-inch) ";
    if ([platform isEqualToString:@"iPad6,8"])   return @"iPad Pro (12.9-inch) ";
    if ([platform isEqualToString:@"iPad6,3"])   return @"iPad Pro (9.7-inch)";
    if ([platform isEqualToString:@"iPad6,4"])   return @"iPad Pro (9.7-inch)";
    if ([platform isEqualToString:@"iPad7,1"])   return @"iPad Pro (12.9-inch) (2nd generation) ";
    if ([platform isEqualToString:@"iPad7,2"])   return @"iPad Pro (12.9-inch) (2nd generation) ";
    if ([platform isEqualToString:@"iPad7,3"])   return @"iPad Pro (10.5-inch)";
    if ([platform isEqualToString:@"iPad7,4"])   return @"iPad Pro (10.5-inch)";
    if ([platform isEqualToString:@"iPad8,1"])   return @"iPad Pro (11-inch)";
    if ([platform isEqualToString:@"iPad8,2"])   return @"iPad Pro (11-inch)";
    if ([platform isEqualToString:@"iPad8,3"])   return @"iPad Pro (11-inch)";
    if ([platform isEqualToString:@"iPad8,4"])   return @"iPad Pro (11-inch)";
    if ([platform isEqualToString:@"iPad8,5"])   return @"iPad Pro (12.9-inch) (3rd generation)";
    if ([platform isEqualToString:@"iPad8,6"])   return @"iPad Pro (12.9-inch) (3rd generation)";
    if ([platform isEqualToString:@"iPad8,7"])   return @"iPad Pro (12.9-inch) (3rd generation)";
    if ([platform isEqualToString:@"iPad8,8"])   return @"iPad Pro (12.9-inch) (3rd generation)";
    if ([platform isEqualToString:@"iPad8,9"])   return @"iPad Pro (11-inch) (2nd generation)";
    if ([platform isEqualToString:@"iPad8,10"])   return @"iPad Pro (11-inch) (2nd generation)";
    if ([platform isEqualToString:@"iPad8,11"])   return @"iPad Pro (12.9-inch) (4th generation)";
    if ([platform isEqualToString:@"iPad8,12"])   return @"iPad Pro (12.9-inch) (4th generation)";
    if ([platform isEqualToString:@"iPad2,5"])   return @"iPad mini";
    if ([platform isEqualToString:@"iPad2,6"])   return @"iPad mini";
    if ([platform isEqualToString:@"iPad2,7"])   return @"iPad mini";
    if ([platform isEqualToString:@"iPad4,4"])   return @"iPad mini 2";
    if ([platform isEqualToString:@"iPad4,5"])   return @"iPad mini 2";
    if ([platform isEqualToString:@"iPad4,6"])   return @"iPad mini 2";
    if ([platform isEqualToString:@"iPad4,7"])   return @"iPad mini 3";
    if ([platform isEqualToString:@"iPad4,8"])   return @"iPad mini 3";
    if ([platform isEqualToString:@"iPad4,9"])   return @"iPad mini 3";
    if ([platform isEqualToString:@"iPad5,1"])   return @"iPad mini 4";
    if ([platform isEqualToString:@"iPad5,2"])   return @"iPad mini 4";
    if ([platform isEqualToString:@"iPad11,1"])   return @"iPad mini 5";
    if ([platform isEqualToString:@"iPad11,2"])   return @"iPad mini 5";

    return @"Unknown iPad";
}

#pragma mark - iPod
NSString *iPodPlatform(NSString *platform){
    
    if ([platform isEqualToString:@"iPod1,1"])      return @"iPod Touch";
    if ([platform isEqualToString:@"iPod2,1"])      return @"iPod touch (2nd generation)";
    if ([platform isEqualToString:@"iPod3,1"])      return @"iPod touch (3rd generation)";
    if ([platform isEqualToString:@"iPod4,1"])      return @"iPod touch (4th generation)";
    if ([platform isEqualToString:@"iPod5,1"])      return @"iPod Touch (5th generation)";
    if ([platform isEqualToString:@"iPod7,1"])      return @"iPod touch (6th generation)";
    //2019年5月发布，更新一种机型：iPod touch (7th generation)
    if ([platform isEqualToString:@"iPod9,1"])      return @"iPod touch (7th generation)";

    return @"Unknown iPod";
}

#pragma mark - AirPods
NSString *AirPodsPlatform(NSString *platform){
    
    if ([platform isEqualToString:@"AirPods1,1"])      return @"AirPods (1st generation)";
    if ([platform isEqualToString:@"AirPods2,1"])      return @"AirPods (2nd generation)";
    if ([platform isEqualToString:@"AirPods8,1"])      return @"AirPods Pro";

    return @"Unknown AirPods";
}

#pragma mark - Apple TV
NSString *AppleTVPlatform(NSString *platform){
    
    if ([platform isEqualToString:@"AppleTV2,1"])      return @"Apple TV (2nd generation)";
    if ([platform isEqualToString:@"AppleTV3,1"])      return @"Apple TV (3rd generation)";
    if ([platform isEqualToString:@"AppleTV5,3"])      return @"Apple TV (4th generation)";
    if ([platform isEqualToString:@"AppleTV6,2"])      return @"Apple TV 4K ";

    return @"Unknown Apple TV";
}

#pragma mark - Apple Watch
NSString *AppleWatchPlatform(NSString *platform){
    
    if ([platform isEqualToString:@"Watch1,1"])      return @"Apple Watch (1st generation)";
    if ([platform isEqualToString:@"Watch1,2"])      return @"Apple Watch (1st generation)";
    if ([platform isEqualToString:@"Watch2,6"])      return @"Apple Watch Series 1";
    if ([platform isEqualToString:@"Watch2,7"])      return @"Apple Watch Series 1";
    if ([platform isEqualToString:@"Watch2,3"])      return @"Apple Watch Series 2";
    if ([platform isEqualToString:@"Watch2,4"])      return @"Apple Watch Series 2";
    if ([platform isEqualToString:@"Watch3,1"])      return @"Apple Watch Series 3";
    if ([platform isEqualToString:@"Watch3,2"])      return @"Apple Watch Series 3";
    if ([platform isEqualToString:@"Watch3,3"])      return @"Apple Watch Series 3";
    if ([platform isEqualToString:@"Watch3,4"])      return @"Apple Watch Series 3";
    if ([platform isEqualToString:@"Watch4,1"])      return @"Apple Watch Series 4";
    if ([platform isEqualToString:@"Watch4,2"])      return @"Apple Watch Series 4";
    if ([platform isEqualToString:@"Watch4,3"])      return @"Apple Watch Series 4";
    if ([platform isEqualToString:@"Watch4,4"])      return @"Apple Watch Series 4";

    return @"Unknown Apple Watch";
}

#pragma mark - HomePod
NSString *HomePodPlatform(NSString *platform){
    
    if ([platform isEqualToString:@"AudioAccessory1,1"])      return @"HomePod";
    if ([platform isEqualToString:@"AudioAccessory1,2"])      return @"HomePod";

    return @"Unknown HomePod";
}

@end

@implementation UIApplication (CLExtension)

+ (double)currentTimestamp{
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return (tv.tv_sec * 1000. + tv.tv_usec / 1000.);
}

+ (double)machTimeToSecs:(uint64_t)time{
    mach_timebase_info_data_t timebase;
    mach_timebase_info(&timebase);
    return (double)time * (double)timebase.numer /
    (double)timebase.denom /1e9;
}

@end
